﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using TP2.Lib;
using System.Xml.Serialization;
using System.Timers;

namespace TP2.Lib
{
    [Serializable]
    public class AvionJugador : VehiculoAereo
    {
        const int VIDA_MAX_JUGADOR = 100,
                  VIDA_JUGADOR = 100,
                  RAPIDEZ_JUGADOR = 3,
                  RADIO_JUGADOR = 32,
                  PUNTOS_PARA_GANAR = 100,
                  DELTA_TIEMPO = 300;
        
       
        #region /* --------- Propiedades --------------*/

        private static Timer Tiempo;
        //private Timer _tiempo;
        //public Timer Tiempo
        //{
        //    get { return this._tiempo; }
        //    set { this._tiempo = value; }
        //}

        private bool _puedeDisparar;
        public bool PuedeDisparar
        {
            get { return this._puedeDisparar; }
            set { this._puedeDisparar = value; }
        }

        private int _puntosAcumulados;
        public int PuntosAcumulados
        {
            get { return this._puntosAcumulados; }
            set { this._puntosAcumulados = value;}
        }
        
        private double[] _posicionContrarioCercana = new double[3];
        public double[] PosicionContrarioCercana
        {
            get {return this._posicionContrarioCercana;}
            set { this._posicionContrarioCercana = value; }
        }

        public bool GanoMision() 
        {
            return (this.PuntosAcumulados >= PUNTOS_PARA_GANAR);
        }

        #endregion

        private AvionJugador() { }

        public AvionJugador(double[] posicion, int[] dimensiones) : base(posicion, dimensiones)
        {
            this.PuntosAcumulados = 0;
            this.VidaMaxima = VIDA_MAX_JUGADOR;
            this.Vida = VIDA_JUGADOR;
            this.Rapidez = RAPIDEZ_JUGADOR;
            this.Radio = RADIO_JUGADOR;
            this.PosicionContrarioCercana = null;
            this.PuntosPorDestruccion = 0;
            this.VariableDisparo = 0;
            this.Recorrido = null;
            this.PuedeDisparar = true;
            
            Tiempo = new Timer(DELTA_TIEMPO);
            // Hook up the Elapsed event for the timer.
            Tiempo.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            // Pongo el intervalo en medio segundo
            Tiempo.Interval = DELTA_TIEMPO;
            Tiempo.Enabled = true;


           // this.ArmaAvion = new LanzaLaser(posicion, dimensiones);

            LanzaLaser lanzaLaser = new LanzaLaser(posicion, dimensiones);
            LanzaCohete lanzaCohete = new LanzaCohete(posicion, dimensiones);
            LanzaTorpedoSimple lanzaTorpedoSimple = new LanzaTorpedoSimple(posicion, dimensiones);
            LanzaTorpedoRastreador lanzaTorpedoRastreador = new LanzaTorpedoRastreador(posicion, dimensiones);

            this.AgregarArma(lanzaLaser);
            this.AgregarArma(lanzaCohete);
            this.AgregarArma(lanzaTorpedoSimple);
            this.AgregarArma(lanzaTorpedoRastreador);
        }

        public void ActualizaPuntos(int puntos) 
        { 
            this.PuntosAcumulados += puntos; 
        }  

        public Proyectil Disparar(Arma arma)
        {
            Type tipoArma = arma.GetType();
            Proyectil proyectil;
            double[] inicio = new double[3];
            double[] final = new double[3];
            
            inicio[0] = this.Posicion[0] + this.Radio;
            inicio[1] = this.Posicion[1] - this.Radio;//Cambio + por - 

            final[0] = this.Posicion[0];
            final[1] = 0;// Cambio this.Dimensiones[1] por 0
            
            for (int index = 0; index <= this.Armas.Count; index++)
            {
                if (PuedeDisparar)
                {                    
                    if (tipoArma == this.Armas.ElementAt(3).GetType())
                    {
                        this.PuedeDisparar = false;
                        //Caso Particular del TorpedoRastreador
                        proyectil = this.Armas.ElementAt(3).Disparar(inicio, this.PosicionContrarioCercana);                        
                        return (proyectil);
                    }
                    else if (tipoArma == this.Armas.ElementAt(index).GetType())
                    {
                        this.PuedeDisparar = false;
                        proyectil = this.Armas.ElementAt(index).Disparar(inicio, final);                        
                        return (proyectil);
                    }                    
                }
            }
            return (null);
        }

        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
           this.PuedeDisparar = true;
        }

        
        /*----Metodos abstractos heredados: obligados a definirlos------*/

        public override void AgregateALista(List<ElementoJuego> lista1, List<ElementoJuego> lista2)
        {
            lista1.Add(this);
        }

        public override Proyectil Actuar()
        {
            //el jugador no actua pues lo maneja el usuario y no el sistema
            return (null);
        }

        public override void Impactar(ElementoJuego impactante)
        {
            impactante.ImpactarConAvionJugador();
        }

        public override void ImpactarConArma(Arma impactante)
        {
       
            //impactante.ImpactarConAvionJugador();

            Type tipo;
            tipo = impactante.GetType();

            foreach (Arma arma in this.Armas)
            {                
                if (tipo == arma.GetType()) { arma.IncrementarArma(); }
            }
        }

        public override bool ImpactarConProyectil(Proyectil impactante)
        {
            //impactante.ImpactarConAvionJugador();
            this.ModificarVida(impactante.Danio);
            return (this.EstoyVivo());
        }

        public override void ImpactarConAvionCivil()
        {
            this.ModificarVida(this.Vida);
        }

        public override void ImpactarConAvionEnemigo()
        {
            this.ModificarVida(this.Vida);
        }

        public override void ImpactarConAvionJugador()
        {
            //Supongo que estos elementos no se impactan.
        }

        public override void ImpactarConHelicopteroPolicia()
        {
            this.ModificarVida(this.Vida);
        }

        public override void ImpactarConTanqueEnergia(TanqueEnergia impactante)
        {
            //impactante.ImpactarConAvionJugador();
            this.ModificarVida((impactante.Energia)*(-1));
            if (this.Vida > this.VidaMaxima)
            {
                this.Vida = VidaMaxima;
            }
        }

        public override void SetearPosicionContrarioCercana(List<ElementoJuego> vehiculosEnemigos)
        {
            this.PosicionContrarioCercana = this.BuscarDistanciaMinimaContrario(vehiculosEnemigos);
        }
    }
}
